package org.wesc.boot.service.system.user;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wesc.boot.common.utils.BeanUtil;
import org.wesc.boot.common.utils.PasswordHelper;
import org.wesc.boot.dao.domain.QueryRequest;
import org.wesc.boot.dao.entity.*;
import org.wesc.boot.dao.mapper.UserConfigMapper;
import org.wesc.boot.dao.mapper.UserMapper;
import org.wesc.boot.dao.mapper.UserRoleMapper;
import org.wesc.boot.dao.model.UserQueryModel;
import org.wesc.boot.dao.model.UserResultModel;
import org.wesc.boot.dao.querymapper.UserQueryMapper;
import org.wesc.boot.dao.utils.SortUtil;
import org.wesc.boot.service.system.menu.MenuAdvanceService;
import org.wesc.boot.service.system.router.RouterMeta;
import org.wesc.boot.service.system.router.VueRouter;
import org.wesc.boot.service.utils.TreeUtil;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户服务
 *
 * @author Wesley
 */
@Slf4j
@Service
public class UserAdvanceService implements Serializable {

    private UserMapper userMapper;

    private UserQueryMapper userQueryMapper;

    private UserConfigMapper userConfigMapper;

    private UserRoleMapper userRoleMapper;

    private MenuAdvanceService menuAdvanceService;

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Autowired
    public void setUserQueryMapper(UserQueryMapper userQueryMapper) {
        this.userQueryMapper = userQueryMapper;
    }

    @Autowired
    public void setUserConfigMapper(UserConfigMapper userConfigMapper) {
        this.userConfigMapper = userConfigMapper;
    }

    @Autowired
    public void setUserRoleMapper(UserRoleMapper userRoleMapper) {
        this.userRoleMapper = userRoleMapper;
    }

    @Autowired
    public void setMenuAdvanceService(MenuAdvanceService menuAdvanceService) {
        this.menuAdvanceService = menuAdvanceService;
    }

    /**
     * 通过用户名查找用户
     *
     * @param userId userId
     * @return user
     */
    public User findByUserId(long userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(User.USER_ID, userId);
        try {
            return userMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 批量查询
     * @param userIds 用户id列表
     * @return 用户列表
     */
    public List<User> findByUserIds(List<Long> userIds) {
        List<User> userList = new ArrayList<>();
        for (Long id: userIds) {
            userList.add(findByUserId(id));
        }
        return userList;
    }

    /**
     * 通过用户名查找用户
     *
     * @param username username
     * @return user
     */
    public User findByUserName(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(User.USER_NAME, username);
        try {
            return userMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询用户角色集
     */
    public List<Role> queryUserRoles(User user) {
        try {
            return userQueryMapper.findUserRoles(user.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    /**
     * 查询用户菜单集
     */
    public List<Menu> queryUserMenus(User user) {
        try {
            return menuAdvanceService.findUserMenus(user.getUserName());
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    }

    /**
     * 查询用户菜单集
     */
    public List<Menu> queryUserMenus(String username) {
        User user = findByUserName(username);
        return queryUserMenus(user);
    }

    /**
     * 获取用户菜单权限列表
     * 返回的menu对象中只包含有perms
     */
    public List<Menu> queryUserMenuPerms(String username) {
        return menuAdvanceService.findUserMenuPerms(username);
    }

    /**
     * 查询用户配置
     */
    public UserConfig queryUserConfig(long userId) {
        QueryWrapper<UserConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserConfig.USER_ID, userId);
        try {
            return userConfigMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通过用户名构建 Vue路由
     *
     * @param username 用户名
     * @return 路由集合
     */
    public ArrayList<VueRouter<Menu>> getUserRouters(String username) {
        User user = findByUserName(username);
        List<VueRouter<Menu>> routes = new ArrayList<>();
        List<Menu> menus = queryUserMenus(user);
        menus.forEach(menu -> {
            VueRouter<Menu> route = new VueRouter<>();
            route.setId(menu.getMenuId().toString());
            route.setParentId(menu.getParentId().toString());
            route.setIcon(menu.getIcon());
            route.setPath(menu.getPath());
            route.setComponent(menu.getComponent());
            route.setName(menu.getMenuName());
            route.setMeta(new RouterMeta(true, null));
            routes.add(route);
        });
        return TreeUtil.buildVueRouter(routes);
    }

    /**
     * 查询所有用户详情
     *
     * @param model UserQueryModel
     * @param queryRequest queryRequest
     * @return IPage
     */
    public IPage<UserResultModel> findUserDetail(UserQueryModel model, QueryRequest queryRequest) {
        try {
            Page<User> page = new Page<>();
            SortUtil.handlePageSort(queryRequest, page, "userId", SortUtil.ORDER_ASC, false);
            Map<String, Object> params = BeanUtil.beanToMap(model);
            return userQueryMapper.findUserDetail(page, params);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询用户异常");
            return null;
        }
    }

    /**
     * 根据用户名获取单个用户详情
     *
     * @param username 用户名
     * @return 用户信息
     */
    public UserResultModel findDetailByUsername(String username) {
        return userQueryMapper.findDetailByUsername(username);
    }

    /**
     * 根据邮箱获取单个用户详情
     *
     * @param email 邮箱
     * @return 用户信息
     */
    public UserResultModel findDetailByEmail(String email) {
        return userQueryMapper.findDetailByEmail(email);
    }

    /**
     * 根据手机号获取单个用户详情
     *
     * @param mobile 手机号
     * @return 用户信息
     */
    public UserResultModel findDetailByMobile(String mobile) {
        return userQueryMapper.findDetailByMobile(mobile);
    }

    /**
     * 创建用户，并且赋予角色，设置默认个性化界面配置
     */
    @Transactional(rollbackFor = Exception.class)
    public void createUser(UserResultModel userResultModel) {
        // 创建用户
        userResultModel.setCreateTime(LocalDateTime.now());
        userResultModel.setAvatar("default.jpg");
        userResultModel.setPassword(PasswordHelper.encryptDefaultPassword());
        userMapper.insert(userResultModel);

        // 保存用户角色
        String[] ids = userResultModel.getRoleId().split(StringPool.COMMA);
        setUserRoles(userResultModel, ids);

        // 创建用户默认的个性化配置
        initDefaultUserConfig(userResultModel.getUserId());
    }

    /**
     * 创建用户默认的个性化配置
     */
    @Transactional(rollbackFor = Exception.class)
    public void initDefaultUserConfig(long userId) {
        UserConfig userConfig = new UserConfig();
        userConfig.setUserId(userId);
        userConfig.setColor(UserConfigConstants.DEFAULT_COLOR);
        userConfig.setFixHeader(UserConfigConstants.DEFAULT_FIX_HEADER);
        userConfig.setFixSiderbar(UserConfigConstants.DEFAULT_FIX_SIDERBAR);
        userConfig.setLayout(UserConfigConstants.DEFAULT_LAYOUT);
        userConfig.setTheme(UserConfigConstants.DEFAULT_THEME);
        userConfig.setMultiPage(UserConfigConstants.DEFAULT_MULTIPAGE);
        userConfigMapper.insert(userConfig);
    }

    /**
     * 设置用户角色
     */
    private void setUserRoles(User user, String[] roles) {
        Arrays.stream(roles).forEach(roleId -> {
            UserRole ur = new UserRole();
            ur.setUserId(user.getUserId());
            ur.setRoleId(Long.valueOf(roleId));
            this.userRoleMapper.insert(ur);
        });
    }

    /**
     * 更新用户信息及角色
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(UserResultModel userResultModel) {
        userResultModel.setPassword(null);
        userResultModel.setModifyTime(LocalDateTime.now());
        userMapper.updateById(userResultModel);
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userResultModel.getUserId()));
        String[] roles = userResultModel.getRoleId().split(StringPool.COMMA);
        setUserRoles(userResultModel, roles);
    }

    /**
     * 批量删除用户
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUsers(String[] userIds) {
        List<Long> list = new ArrayList<>(userIds.length);
        for (String str : userIds ) {
            list.add(Long.valueOf(str));
        }
        userMapper.deleteBatchIds(list);
        // 删除用户角色
        userRoleMapper.deleteBatchIds(list);
        // 删除用户个性化配置
        userConfigMapper.deleteBatchIds(list);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateProfile(User user) {
        userMapper.updateById(user);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateAvatar(String username, String avatar) {
        User user = new User();
        user.setAvatar(avatar);
        userMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateUserConfig(UserConfig userConfig) {
        userConfigMapper.update(userConfig, new LambdaQueryWrapper<UserConfig>().eq(UserConfig::getUserId, userConfig.getUserId()));
    }

    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(String username, String password) {
        User user = new User();
        user.setPassword(PasswordHelper.encryptPassword(password));
        userMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
    }

    @Transactional(rollbackFor = Exception.class)
    public void resetPassword(String[] userNames) {
        for (String username : userNames) {
            User user = new User();
            user.setPassword(PasswordHelper.encryptDefaultPassword());
            userMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
        }
    }

}
